package com.erpanderp.wam.usm.view.timesheet;

import java.io.IOException;
import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.event.MethodExpressionActionListener;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.swing.SwingWorker;

import org.primefaces.component.menubutton.MenuButton;
import org.primefaces.component.menuitem.MenuItem;
import org.primefaces.context.RequestContext;
import org.primefaces.event.RowEditEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;

import com.erpanderp.wam.ac.model.service.project.ProjectAssignmentDetailDAO;
import com.erpanderp.wam.adm.model.entity.RolePermission;
import com.erpanderp.wam.usm.model.entity.projectandassignment.EmployeeProject;
import com.erpanderp.wam.usm.model.entity.projectandassignment.Project;
import com.erpanderp.wam.usm.model.entity.timesheet.ProjectAssignmentTimesheetDetail;
import com.erpanderp.wam.usm.model.entity.timesheet.Timesheet;
import com.erpanderp.wam.usm.model.entity.timesheet.TimesheetDetail;
import com.erpanderp.wam.usm.model.entity.user.Employee;
import com.erpanderp.wam.usm.model.entity.user.EmployeeAndReporting;
import com.erpanderp.wam.usm.model.entity.user.WAMUser;
import com.erpanderp.wam.usm.model.service.leave.EmployeeLeaveDAO;
import com.erpanderp.wam.usm.model.service.projectandassignment.EmployeeProjectDAO;
import com.erpanderp.wam.usm.model.service.timesheet.ProjectAssignmentTimesheetDetailDAO;
import com.erpanderp.wam.usm.model.service.timesheet.TimesheetDAO;
import com.erpanderp.wam.usm.model.service.timesheet.TimesheetDetailDAO;
import com.erpanderp.wam.usm.model.service.user.EmployeeAndReportingDAO;
import com.erpanderp.wam.usm.model.service.user.EmployeeDAO;
import com.erpanderp.wam.usm.model.service.user.EmployeeRoleDAO;
import com.erpanderp.wam.usm.model.service.user.WAMUserDAO;
import com.erpanderp.wam.util.CommonLookup;
import com.erpanderp.wam.util.EmailUtil;
import com.erpanderp.wam.util.ValidationUtil;
import com.erpanderp.wam.util.WAMHostManager;
import com.erpanderp.wam.util.WAMUtil;

@ManagedBean
@ViewScoped
public class TimesheetsBean {
	HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
			.getExternalContext().getSession(true);
	HttpServletRequest request = (HttpServletRequest) FacesContext
			.getCurrentInstance().getExternalContext().getRequest();
	ServletContext context = (ServletContext) FacesContext.getCurrentInstance()
			.getExternalContext().getContext();
	private WAMUser wamUser = (WAMUser) session
			.getAttribute(CommonLookup.SESSION_ATTRIBUTE_WAMUSER);
	private EmployeeAndReporting employeeAndReporting;
	EmployeeAndReportingDAO employeeAndReportingDAO;
	WAMUserDAO wamUserDAO = new WAMUserDAO();
	private List<TimesheetDetail> timesheetDetails = new LinkedList<TimesheetDetail>();
	WAMUtil wamUtil = new WAMUtil();

	private Long approverId;
	private Employee approver;
	private Map<String, Long> approversMap = new HashMap<String, Long>();

	private MenuButton monthsMenuButton = new MenuButton();
	private String selectedMonth; // selected timesheet month
	String dayNames[] = new DateFormatSymbols().getWeekdays();
	String monthNames[] = new DateFormatSymbols().getMonths();
	private TimeZone defaultTimeZone = TimeZone.getDefault();
	private String timesheetMonth; // actual timesheet month
	private String year;
	private String selectedMonthYear;
	private String timesheetStatus = CommonLookup.TIMESHEET_DETAILS_NOT_FOUND;
	private boolean TIMESHEET_NOT_FOUND;
	private boolean ALLOW_TO_CREATE = true;
	private boolean ALLOW_TO_SUBMIT;
	private boolean IN_PROJECT;
	private Timesheet timesheet = new Timesheet();
	Calendar calendar = Calendar.getInstance();

	TimesheetDAO timesheetDAO;
	TimesheetDetailDAO timesheetDetailDAO = new TimesheetDetailDAO();
	EmployeeDAO employeeDAO = new EmployeeDAO();
	EmployeeRoleDAO employeeRoleDAO = new EmployeeRoleDAO();
	EmployeeProjectDAO employeeProjectDAO = new EmployeeProjectDAO();
	ProjectAssignmentTimesheetDetailDAO projectAssignmentTimesheetDetailDAO = new ProjectAssignmentTimesheetDetailDAO();
	EmailUtil emailUtil;
	String EMAIL_MESSAGE;
	private TimesheetDetail selectedTimesheetDetail = new TimesheetDetail();
	private TimesheetDetail selectedTimesheetDetailEmail;
	private List<ProjectAssignmentTimesheetDetail> projectAssignmentTimesheetDetails = new ArrayList<ProjectAssignmentTimesheetDetail>();
	private boolean SHOW_TIMESHEET_WARN_MESSAGE;

	public TimesheetsBean() {
		System.out.println("CreateTimesheetBean...");
		WAMUser tempWAMUser = getWAMUserByParameter();

		if (wamUser != null) {

			if (tempWAMUser != null
					&& !tempWAMUser.getWAMUserId().equals(
							wamUser.getWAMUserId())) {
				try {
					FacesContext
							.getCurrentInstance()
							.getExternalContext()
							.redirect(
									"/wam/login.html?redirectedfrom="
											+ CommonLookup.PAGE_TIMESHEETS);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (employeeAndReportingDAO == null)
				employeeAndReportingDAO = new EmployeeAndReportingDAO();
			employeeAndReporting = employeeAndReportingDAO
					.getEmployeeReportingDetail(wamUser.getEmployee()
							.getEmployeeId());

			// identify whether user is in project or not
			List<Project> projects = employeeProjectDAO.getAllProjects(wamUser
					.getEmployee().getEmployeeId());
			if (employeeAndReporting.getProject() != null
					&& !employeeAndReporting.getProject().equals(
							CommonLookup.PROJECT_KA) && projects != null
					&& projects.size() > 0) {
				IN_PROJECT = true;
			}

			List<Employee> temp = employeeAndReportingDAO
					.getTimesheetApprovers(wamUser.getEmployee()
							.getEmployeeId());

			if (temp != null) {
				for (Employee employee : temp) {
					approversMap.put(
							employee.getFirstName()
									+ " "
									+ employee.getLastName()
									+ " ("
									+ employeeRoleDAO.getRoleByEmployeeId(
											employee.getEmployeeId()).getRole()
									+ ")", employee.getEmployeeId());
				}
			}

			// Businness rule to maintain timesheet for next month if date > 24
			if (calendar.get(Calendar.DAY_OF_MONTH) > 24) {
				calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
			}

			// set month and year
			timesheetMonth = monthNames[calendar.get(Calendar.MONTH)]
					.toUpperCase();
			year = String.valueOf(calendar.get(Calendar.YEAR));
			selectedMonthYear = timesheetMonth + " " + year;
			setSelectedMonth(timesheetMonth);

			// Generate last six months
			generateMonthsMenu();

			if (timesheetDAO == null)
				timesheetDAO = new TimesheetDAO();
			timesheet = timesheetDAO.getTimesheet(timesheetMonth, Integer
					.parseInt(year), wamUser.getEmployee().getEmployeeId());
			if (timesheet != null) {
				// Load timesheet from database if available..
				loadOrGenerateTimesheetDetails(timesheet);
				TIMESHEET_NOT_FOUND = false;
				System.out.println("NOT NULL;");

				setAllowToSubmit();
			} else {

				approverId = employeeAndReporting.getProjectManager() != null ? employeeAndReporting
						.getProjectManager().getEmployeeId() : null;

				TIMESHEET_NOT_FOUND = true;
				setTimesheetStatus("You have not created timesheet for current month ("
						+ selectedMonthYear + ")");
			}
		} else {
			try {
				FacesContext
						.getCurrentInstance()
						.getExternalContext()
						.redirect(
								"/wam/login.html?redirectedfrom="
										+ CommonLookup.PAGE_TIMESHEETS);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * Gets WAMUser based on employee ID
	 * 
	 * @return
	 */
	private WAMUser getWAMUserByParameter() {
		String employeeCodeParameter = request.getParameter("employeeId");
		System.out.println("Employee Code: " + employeeCodeParameter + " ");
		if (employeeCodeParameter != null && !employeeCodeParameter.equals("")) {
			return wamUserDAO.getWAMUserByEmployeeId(Long
					.parseLong(employeeCodeParameter));
		} else {
			return null;
		}
	}

	public void approverChanged(AjaxBehaviorEvent e) {
		SHOW_TIMESHEET_WARN_MESSAGE = false;
		approver = employeeDAO.getEmployeeByEmployeeId(approverId);
		setApproverForTimesheet(approver);

	}

	private void setApproverForTimesheet(Employee selectedApprover) {
		if (timesheet != null) {
			timesheet.setApprover(selectedApprover);
		} else {

		}
	}

	public void renderEmailConfirmDialog(ActionEvent e) {
		SHOW_TIMESHEET_WARN_MESSAGE = false;
		Long id = (Long) e.getComponent().getAttributes()
				.get("selectedTimesheetDetailEmailId");
		selectedTimesheetDetailEmail = timesheetDetailDAO
				.getTimesheetDetail(id);
		System.out.println(selectedTimesheetDetailEmail);
		RequestContext.getCurrentInstance().addPartialUpdateTarget(
				":timesheetForm:create_timesheet");

	}

	public void sendMail(ActionEvent e) {
		System.out.println("Sending...");
		System.out.println(selectedTimesheetDetailEmail == null);
		System.out.println(selectedTimesheetDetailEmail);
		System.out.println(selectedTimesheetDetailEmail.getTimesheet());
		System.out.println(selectedTimesheetDetailEmail.getActivity());
		System.out.println(selectedTimesheetDetailEmail.getTimesheetDate());
		sendMessage(selectedTimesheetDetailEmail);

	}

	public String sendMessage(TimesheetDetail timesheetDetail) {
		Map<String, String> hostsMap = WAMHostManager.getWAMHosts(context);
		String domainName = context.getInitParameter("domainName");

		// /String[] to =
		// {timesheetDetail.getTimesheet().getApprover().getEmail()};

		emailUtil = new EmailUtil();
		if (hostsMap.get(CommonLookup.DEV_EMAIL) == null) {

			String[] to = { timesheetDetail.getTimesheet().getApprover()
					.getEmail() };
			emailUtil.setRecieverAddresses(to);
		} else {
			System.out
					.println("Email: " + hostsMap.get(CommonLookup.DEV_EMAIL));
			String[] to = { hostsMap.get(CommonLookup.DEV_EMAIL) };
			System.out.println(to);
			emailUtil.setRecieverAddresses(to);
		}

		SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy");
		String messageString = "Dear " + timesheet.getApprover().getFirstName()
				+ " " + timesheet.getApprover().getLastName() + "" + ",<br />"
				+ "<h3>Daily Activity submitted by "
				+ timesheet.getEmployee().getFirstName() + " "
				+ timesheet.getEmployee().getLastName() + " ("
				+ timesheet.getEmployee().getEmployeeCode() + ")</h3>"
				+ "<table style='border: 1px solid #d9d9d9;'>"
				+ "<tr> <td>Date</td><td>: </td><td>"
				+ formatter.format(timesheetDetail.getTimesheetDate())
				+ " </td></tr>" + "<tr> <td>Activity</td><td>: </td><td>"
				+ timesheetDetail.getActivity() + " </td></tr>"
				+ "<tr> <td>In Time</td><td>: </td> <td>"
				+ timesheetDetail.getInTimeString() + " </td></tr>"
				+ "<tr> <td>Out Time</td><td> : </td> <td>"
				+ timesheetDetail.getOutTimeString() + "</td></tr>"
				+ "<tr> <td>Duration</td><td> : </td> <td>"
				+ timesheetDetail.getDuration() + "</td></tr>"
				+ "</table><br/>" +

				"Thanks & Regards, <br />" + CommonLookup.WAM_DEVTEAM_SIGNATURE;
		;

		emailUtil.setMessage(messageString);
		// emailUtil.setRecieverAddresses(to);
		emailUtil.setSenderEmail("podquick@erpanderp.com", "WAM - Dev Team");
		emailUtil.setSubject("WAM - Daily Activity - "
				+ timesheet.getEmployee().getEmployeeCode() + " ("
				+ formatter.format(timesheetDetail.getTimesheetDate()) + ")");

		SwingWorker worker = new SwingWorker<String, Object>() {
			@Override
			protected String doInBackground() throws Exception {
				EMAIL_MESSAGE = emailUtil.processAndSendEmail();
				return null;
			}

			@Override
			protected void done() {
				System.out.println("DONE " + EMAIL_MESSAGE);
			}
		};
		worker.execute();
		System.out.println("BEFORE RETURNING: " + EMAIL_MESSAGE);
		return EMAIL_MESSAGE;
	}

	/**
	 * Method to generate last 6 months...
	 */
	public void generateMonthsMenu() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.MONTH, this.calendar.get(Calendar.MONTH));
		calendar.set(Calendar.YEAR, this.calendar.get(Calendar.YEAR));
		calendar.set(Calendar.DAY_OF_MONTH, 1);// Just set to a date common to
												// all 12 months

		MenuItem item = new MenuItem();
		item.setValue(monthNames[calendar.get(Calendar.MONTH)].toUpperCase()
				+ " " + String.valueOf(calendar.get(Calendar.YEAR)));
		item.addActionListener(createActionListener("#{timesheetsBean.monthsMenuAction}"));
		// item.setAjax(false);
		item.setUpdate("@form");
		monthsMenuButton.getChildren().add(item);

		for (int i = 1; i <= 5; i++) {
			calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
			System.out.println(calendar.getTime());
			item = new MenuItem();
			item.setValue(monthNames[calendar.get(Calendar.MONTH)]
					.toUpperCase()
					+ " "
					+ String.valueOf(calendar.get(Calendar.YEAR)));
			item.addActionListener(createActionListener("#{timesheetsBean.monthsMenuAction}"));
			// item.setAjax(false);
			item.setUpdate("@form");
			monthsMenuButton.getChildren().add(item);
		}

	}

	public static MethodExpressionActionListener createActionListener(
			String actionListenerExpression) {
		FacesContext context = FacesContext.getCurrentInstance();
		return new MethodExpressionActionListener(context
				.getApplication()
				.getExpressionFactory()
				.createMethodExpression(context.getELContext(),
						actionListenerExpression, null,
						new Class[] { ActionEvent.class }));
	}

	public void monthsMenuAction(ActionEvent e) {
		SHOW_TIMESHEET_WARN_MESSAGE = false;
		System.out.println("Months Menu Action...");
		selectedMonthYear = ((MenuItem) e.getComponent()).getValue().toString();

		if (timesheetDAO == null)
			timesheetDAO = new TimesheetDAO();
		timesheet = timesheetDAO.getTimesheet(selectedMonthYear.substring(0,
				selectedMonthYear.length() - 5), Integer
				.parseInt(selectedMonthYear.substring(selectedMonthYear
						.length() - 4)), wamUser.getEmployee().getEmployeeId());
		System.out.println("Selected month year : " + selectedMonthYear);
		if (timesheet != null) {
			loadOrGenerateTimesheetDetails(timesheet);
			TIMESHEET_NOT_FOUND = false;
		} else {
			TIMESHEET_NOT_FOUND = true;
			setTimesheetStatus("You have not created timesheet for selected month ("
					+ selectedMonthYear + ")");
			if (selectedMonthYear.equals(timesheetMonth + " "
					+ String.valueOf(year))) {
				ALLOW_TO_CREATE = true;
			} else {
				ALLOW_TO_CREATE = false;
			}
		}
		setSelectedMonth(selectedMonthYear.substring(0,
				selectedMonthYear.length() - 5));
		setAllowToSubmit();
	}

	private void loadOrGenerateTimesheetDetails(Timesheet timesheet) {
		if (timesheet != null) {
			// Loading...
			if (timesheetDetailDAO == null)
				timesheetDetailDAO = new TimesheetDetailDAO();
			timesheetDetails = new LinkedList<TimesheetDetail>();
			timesheetDetails.addAll(timesheet.getTimesheetDetails());
			Collections.sort(timesheetDetails);
			approverId = timesheet.getApprover().getEmployeeId();
			System.out.println("From DB: " + approverId);
		} else {
			timesheetDetails = new LinkedList<TimesheetDetail>();
			// Generating...
			System.out.println("A ID: " + approverId);
			this.timesheet = new Timesheet();
			approver = employeeDAO.getEmployeeByEmployeeId(approverId);
			setApproverForTimesheet(approver);

			Date startDate = null;
			Date endDate = null;
			endDate = wamUtil.getTimesheetEndDate(selectedMonth);
			Calendar temp = Calendar.getInstance();
			temp.setTime(endDate);
			startDate = wamUtil.getTimesheetStartDate(temp);
			Map<Date, String> leavesMap = new EmployeeLeaveDAO()
					.getApprovedEmployeeLeaveDates(startDate, endDate, wamUser
							.getEmployee().getEmployeeId());

			while (startDate.before(endDate) || startDate.equals(endDate)) {
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(startDate);

				TimesheetDetail timesheetDetail = new TimesheetDetail();
				timesheetDetail.setTimesheetDate(startDate);
				timesheetDetail.setDayOfWeek(dayNames[calendar
						.get(Calendar.DAY_OF_WEEK)]);
				if (timesheetDetail.getDayOfWeek().equalsIgnoreCase("Saturday")
						|| timesheetDetail.getDayOfWeek().equalsIgnoreCase(
								"Sunday")) {
					timesheetDetail.setActivity(CommonLookup.TEXT_WEEK_OFF);
				}

				// Other Attributes...
				timesheetDetail.setCreateDate(new Date());
				timesheetDetail.setCreatedBy(wamUser.getEmployee()
						.getFirstName());
				timesheetDetail.setStatus(CommonLookup.STATUS_ACTIVE);
				timesheetDetail.setTimesheet(this.timesheet);

				System.out.println("startdate: " + startDate);
				// Set the timesheetdetailstatus based on leave applied.
				if (leavesMap != null && leavesMap.containsKey(startDate)) {
					timesheetDetail.setTimesheetDetailStatus(leavesMap
							.get(startDate));
				}
				timesheetDetails.add(timesheetDetail);

				calendar.add(Calendar.DAY_OF_MONTH, 1);
				startDate = calendar.getTime();

				if (IN_PROJECT) {
					List<EmployeeProject> employeeProjects = employeeProjectDAO
							.getAllEmployeeProjects(wamUser.getEmployee()
									.getEmployeeId());

					if (employeeProjects != null && employeeProjects.size() > 0) {
						for (EmployeeProject employeeProject : employeeProjects) {
							ProjectAssignmentTimesheetDetail assignmentTimesheetDetail = new ProjectAssignmentTimesheetDetail();
							assignmentTimesheetDetail
									.setEmployeeProject(employeeProject);
							assignmentTimesheetDetail.setTimeSpent("00.00");
							assignmentTimesheetDetail
									.setTimesheetDetail(timesheetDetail);
							timesheetDetail
									.getProjectAssignmentTimesheetDetails()
									.add(assignmentTimesheetDetail);
							employeeProject
									.getProjectAssignmentTimesheetDetails()
									.add(assignmentTimesheetDetail);
						}
					}
				}
			}

			this.timesheet.getTimesheetDetails().addAll(timesheetDetails);
			if (saveTimesheet()) {
				TIMESHEET_NOT_FOUND = false;
				FacesContext.getCurrentInstance().addMessage(
						null,
						new FacesMessage(FacesMessage.SEVERITY_INFO,
								"Timesheet has been generated and saved.", ""));
			} else {
				FacesContext.getCurrentInstance().addMessage(
						null,
						new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR.",
								""));
				TIMESHEET_NOT_FOUND = true;
			}
		}

	}

	public void saveTimesheetDetail(RowEditEvent e) {
		SHOW_TIMESHEET_WARN_MESSAGE = false;

		System.out.println("Saving...");
		TimesheetDetail timesheetDetail = (TimesheetDetail) e.getObject();
		timesheetDetail.setDateModified(new Date());
		timesheetDetail.setModifiedBy(wamUser.getEmployee().getFirstName());
		timesheetDetail.setTimesheet(timesheet);

		if (validateTimesheetDetail(timesheetDetail)) {
			System.out.println("VALID");
			if (timesheetDetailDAO == null)
				timesheetDetailDAO = new TimesheetDetailDAO();
			if (timesheetDetailDAO.updateTimesheetDetail(timesheetDetail) != null) {
				FacesContext.getCurrentInstance().addMessage(
						null,
						new FacesMessage(FacesMessage.SEVERITY_INFO,
								"Timesheet Detail updated.", ""));
			} else {
				FacesContext.getCurrentInstance().addMessage(
						null,
						new FacesMessage(FacesMessage.SEVERITY_WARN,
								"Timesheet Detail was not updated.", ""));
			}
		} else {
			System.out.println("INVALID...");
			loadOrGenerateTimesheetDetails(timesheet);

			// FacesContext.getCurrentInstance().addMessage(null, new
			// FacesMessage(FacesMessage.SEVERITY_WARN,
			// "Timesheet Detail was not saved. Please fill your activity.",
			// ""));
		}

		RequestContext.getCurrentInstance().addPartialUpdateTarget("growl");
	}

	private boolean validateTimesheetDetail(TimesheetDetail timesheetDetail) {
		boolean VALID = true;
		System.out.println("." + timesheetDetail.getActivity() + ".");

		if (!timesheetDetail.getDayOfWeek().equals("Sunday")
				&& !timesheetDetail.getDayOfWeek().equals("Saturday")) {
			if (!IN_PROJECT
					&& ValidationUtil.isEmpty(timesheetDetail.getActivity(),
							"Activity ", "Activity ",
							FacesContext.getCurrentInstance()) != null) {
				VALID = false;
			}

			boolean INVALID_TIME_FOUND = false;
			if (ValidationUtil.isEmpty(timesheetDetail.getInTimeString(),
					"In Time ", "In Time ", FacesContext.getCurrentInstance()) != null) {
				VALID = false;
				INVALID_TIME_FOUND = true;
			} else if (ValidationUtil.validate24HoursTime(
					timesheetDetail.getInTimeString(), "In Time is", "",
					FacesContext.getCurrentInstance()) != null) {
				VALID = false;
				INVALID_TIME_FOUND = true;
			}

			if (ValidationUtil
					.isEmpty(timesheetDetail.getOutTimeString(), "Out Time ",
							"Out Time ", FacesContext.getCurrentInstance()) != null) {
				VALID = false;
				INVALID_TIME_FOUND = true;
			} else if (ValidationUtil.validate24HoursTime(
					timesheetDetail.getOutTimeString(), "Out Time is", "",
					FacesContext.getCurrentInstance()) != null) {
				VALID = false;
				INVALID_TIME_FOUND = true;
			}

			if (!INVALID_TIME_FOUND) {
				String timeDiff = ValidationUtil.getTimeDifference(
						timesheetDetail.getInTimeString(),
						timesheetDetail.getOutTimeString(), "");
				if (timeDiff != null && timeDiff.equals("INVALID TIMES")) {
					VALID = false;
					INVALID_TIME_FOUND = true;
				} else {
					System.out.println("Diff: " + timeDiff);
					timesheetDetail.setDuration(timeDiff);
				}
			}
		} else {
			boolean INVALID_TIME_FOUND = false;

			if (ValidationUtil.isEmpty(timesheetDetail.getInTimeString(),
					"In Time ", "In Time ", FacesContext.getCurrentInstance()) != null) {
				timesheetDetail.setInTimeString("09:30");
			} else if (ValidationUtil.validate24HoursTime(
					timesheetDetail.getInTimeString(), "In Time is", "",
					FacesContext.getCurrentInstance()) != null) {
				VALID = false;
				INVALID_TIME_FOUND = true;
			}

			if (ValidationUtil
					.isEmpty(timesheetDetail.getOutTimeString(), "Out Time ",
							"Out Time ", FacesContext.getCurrentInstance()) != null) {
				timesheetDetail.setOutTimeString("18:30");
			} else if (ValidationUtil.validate24HoursTime(
					timesheetDetail.getOutTimeString(), "Out Time is", "",
					FacesContext.getCurrentInstance()) != null) {
				VALID = false;
				INVALID_TIME_FOUND = true;
			}

			if (!INVALID_TIME_FOUND) {
				String timeDiff = ValidationUtil.getTimeDifference(
						timesheetDetail.getInTimeString(),
						timesheetDetail.getOutTimeString(), "");
				if (timeDiff != null && timeDiff.equals("INVALID TIMES")) {
					VALID = false;
					INVALID_TIME_FOUND = true;
				} else {
					timesheetDetail.setDuration(timeDiff);
				}
			}
		}

		return VALID;
	}

	private void clearStyles() {
		for (TimesheetDetail detail : timesheetDetails) {
			detail.getStylesMap().put("inTimeString", "");
			detail.getStylesMap().put("outTimeString", "");
			detail.getStylesMap().put("activity", "");
		}
	}

	private boolean saveTimesheet() {
		SHOW_TIMESHEET_WARN_MESSAGE = false;
		Date now = new Date();

		timesheet.setCreateDate(now);
		timesheet.setCreatedBy(wamUser.getEmployee().getFirstName());
		timesheet.setEmployee(wamUser.getEmployee());
		timesheet.setMonth(timesheetMonth);
		// timesheet.setSubmittedOn(now);
		timesheet
				.setTimesheetStatus(CommonLookup.TIMESHEET_STATUS_NOT_SUBMITTED);
		timesheet.setYear(Integer.parseInt(year));
		timesheet.getTimesheetDetails().addAll(timesheetDetails);
		timesheet.setStatus(CommonLookup.STATUS_ACTIVE);
		timesheet.getTimesheetDetails().addAll(timesheetDetails);
		if (timesheetDAO == null)
			timesheetDAO = new TimesheetDAO();

		if (timesheetDAO.createTimesheet(timesheet) != null) {
			return true;
		} else {
			return false;
		}
	}

	public void submitTimesheet(ActionEvent e) {
		System.out.println("Submitting...");
		Date now = new Date();
		timesheet.setDateModified(now);
		timesheet.setModifiedBy(wamUser.getEmployee().getFirstName());
		timesheet.setSubmittedOn(now);
		timesheet
				.setTimesheetStatus(CommonLookup.TIMESHEET_STATUS_TO_BE_APPROVED);

		if (timesheetDAO == null)
			timesheetDAO = new TimesheetDAO();
		if (timesheetDAO.updateTimesheet(timesheet) != null) {
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_INFO,
							"Your timesheet has been submitted successfully.",
							""));
		} else {
			FacesContext
					.getCurrentInstance()
					.addMessage(
							null,
							new FacesMessage(
									FacesMessage.SEVERITY_WARN,
									"Your timesheet could not be submitted, please try again.",
									""));
		}

	}

	public void submitTimesheetAction(ActionEvent e) {
		if (allActivitiesFilled()) {
			RequestContext.getCurrentInstance().execute("confirmation.show()");
			SHOW_TIMESHEET_WARN_MESSAGE = false;
		} else {
			FacesContext
					.getCurrentInstance()
					.addMessage(
							null,
							new FacesMessage(
									FacesMessage.SEVERITY_INFO,
									"Please fill all the activities to submit your timesheet.",
									""));
			SHOW_TIMESHEET_WARN_MESSAGE = true;
			RequestContext.getCurrentInstance().execute("confirmation.hide()");
		}

	}

	public boolean allActivitiesFilled() {
		for (TimesheetDetail timesheetDetail : timesheetDetails) {
			if ((timesheetDetail.getTimesheetDetailStatus() == null || timesheetDetail.getTimesheetDetailStatus().equals('P')) && !timesheetDetail.getDayOfWeek().trim().startsWith("S") ) {
				if (IN_PROJECT) {
					boolean ACTIVITY_FOUND = false;
					for (ProjectAssignmentTimesheetDetail projectAssignmentTimesheetDetail : timesheetDetail
							.getProjectAssignmentTimesheetDetails()) {
						if (projectAssignmentTimesheetDetail.getActivity() != null
								&& !projectAssignmentTimesheetDetail
										.getActivity().equals("")) {
							ACTIVITY_FOUND = true;
							break;
						}
					}
					if (!ACTIVITY_FOUND)
						return false;
				} else {
					if (timesheetDetail.getActivity() == null
							|| timesheetDetail.getActivity().equals("")) {
						System.out.println(timesheetDetail.getTimesheetDate());
						System.out.println("false,....");
						return false;
					}
				}
			}

		}
		return true;
	}

	public void onRowSelect(SelectEvent event) {
		FacesMessage msg = new FacesMessage("Selected",
				((TimesheetDetail) event.getObject()).getTimesheetDate()
						.toString());

		FacesContext.getCurrentInstance().addMessage(null, msg);
	}

	public void onRowUnselect(UnselectEvent event) {
		FacesMessage msg = new FacesMessage("UnSelected",
				((TimesheetDetail) event.getObject()).getTimesheetDate()
						.toString());

		FacesContext.getCurrentInstance().addMessage(null, msg);
	}

	public void onRowDblselect(SelectEvent event) {
		System.out.println("Something happen...");
	}

	public void createTimesheetButtonAction(ActionEvent e) {
		loadOrGenerateTimesheetDetails(null);
		setAllowToSubmit();
	}

	public EmployeeAndReporting getEmployeeAndReporting() {
		return employeeAndReporting;
	}

	public void setEmployeeAndReporting(
			EmployeeAndReporting employeeAndReporting) {
		this.employeeAndReporting = employeeAndReporting;
	}

	public WAMUser getWamUser() {
		return wamUser;
	}

	public void setWamUser(WAMUser wamUser) {
		this.wamUser = wamUser;
	}

	public List<TimesheetDetail> getTimesheetDetails() {
		return timesheetDetails;
	}

	public void setTimesheetDetails(List<TimesheetDetail> timesheetDetails) {
		this.timesheetDetails = timesheetDetails;
	}

	public TimeZone getDefaultTimeZone() {
		return defaultTimeZone;
	}

	public void setDefaultTimeZone(TimeZone defaultTimeZone) {
		this.defaultTimeZone = defaultTimeZone;
	}

	public String getTimesheetMonth() {
		return timesheetMonth;
	}

	public void setTimesheetMonth(String timesheetMonth) {
		this.timesheetMonth = timesheetMonth;
	}

	public String getYear() {
		return year;
	}

	public void setYear(String year) {
		this.year = year;
	}

	public String getTimesheetStatus() {
		return timesheetStatus;
	}

	public void setTimesheetStatus(String timesheetStatus) {
		this.timesheetStatus = timesheetStatus;
	}

	public boolean isTIMESHEET_NOT_FOUND() {
		return TIMESHEET_NOT_FOUND;
	}

	public void setTIMESHEET_NOT_FOUND(boolean tIMESHEET_NOT_FOUND) {
		TIMESHEET_NOT_FOUND = tIMESHEET_NOT_FOUND;
	}

	public Timesheet getTimesheet() {
		return timesheet;
	}

	public void setTimesheet(Timesheet timesheet) {
		this.timesheet = timesheet;
	}

	public MenuButton getMonthsMenuButton() {
		return monthsMenuButton;
	}

	public void setMonthsMenuButton(MenuButton monthsMenuButton) {
		this.monthsMenuButton = monthsMenuButton;
	}

	public String getSelectedMonth() {
		return selectedMonth;
	}

	public void setSelectedMonth(String selectedMonth) {
		this.selectedMonth = selectedMonth;
	}

	public String getSelectedMonthYear() {
		return selectedMonthYear;
	}

	public void setSelectedMonthYear(String selectedMonthYear) {
		this.selectedMonthYear = selectedMonthYear;
	}

	public boolean isALLOW_TO_CREATE() {
		return ALLOW_TO_CREATE;
	}

	public void setALLOW_TO_CREATE(boolean aLLOW_TO_CREATE) {
		ALLOW_TO_CREATE = aLLOW_TO_CREATE;
	}

	public boolean isALLOW_TO_SUBMIT() {
		return ALLOW_TO_SUBMIT;
	}

	public void setALLOW_TO_SUBMIT(boolean aLLOW_TO_SUBMIT) {
		ALLOW_TO_SUBMIT = aLLOW_TO_SUBMIT;
		System.out.println("SETTER");
	}

	private void setAllowToSubmit() {
		Map<String, Integer> monthsMap = new HashMap<String, Integer>();
		Integer selectedMonthNo = monthsMap.get(selectedMonth);

		Date timesheetEndDate = wamUtil.getTimesheetEndDate(selectedMonth);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(timesheetEndDate);
		calendar.set(Calendar.DAY_OF_MONTH, 28);
		timesheetEndDate = calendar.getTime();

		if (new Date().before(timesheetEndDate)) {
			String status = (timesheet != null && timesheet
					.getTimesheetStatus() != null) ? timesheet
					.getTimesheetStatus() : null;
			if (status != null
					&& (status.equals(CommonLookup.TIMESHEET_STATUS_REJECTED) || status
							.equals(CommonLookup.TIMESHEET_STATUS_NOT_SUBMITTED))) {
				ALLOW_TO_SUBMIT = true;
			} else {
				ALLOW_TO_SUBMIT = false;
			}
		} else {
			ALLOW_TO_SUBMIT = false;
		}
	}

	public void showDetailActivityDialog(SelectEvent e) {
		selectedTimesheetDetail = (TimesheetDetail) (TimesheetDetail) e
				.getObject();
		projectAssignmentTimesheetDetails.clear();
		projectAssignmentTimesheetDetails.addAll(selectedTimesheetDetail
						.getProjectAssignmentTimesheetDetails());
		if (IN_PROJECT
				&& (timesheet.getTimesheetStatus().equals(
						CommonLookup.TIMESHEET_STATUS_NOT_SUBMITTED) || timesheet
						.getTimesheetStatus().equals(
								CommonLookup.TIMESHEET_STATUS_REJECTED))) {
			RequestContext.getCurrentInstance().execute(
					"detailActivityDialog.show()");
		}

	}

	public void updateAssignmentActivity(ActionEvent e) {
		System.out.println("Saving...");

		if (validateAssignmentActivity()) {
			System.out.println("VALID");
			for (ProjectAssignmentTimesheetDetail projectAssignmentTimesheetDetail : projectAssignmentTimesheetDetails) {
				projectAssignmentTimesheetDetail.setDateModified(new Date());
				projectAssignmentTimesheetDetail.setModifiedBy(wamUser
						.getEmployee().getFirstName());
			}
			selectedTimesheetDetail.setActivity(CommonLookup.TEXT_WORKED);
			if (timesheetDetailDAO
					.updateTimesheetDetail(selectedTimesheetDetail) != null
					&& projectAssignmentTimesheetDetailDAO
							.updateTimesheetDetails(projectAssignmentTimesheetDetails)) {
				FacesContext
						.getCurrentInstance()
						.addMessage(
								null,
								new FacesMessage(
										FacesMessage.SEVERITY_INFO,
										"Timesheet Details has been updated successfully.",
										""));
			} else {
				FacesContext.getCurrentInstance().addMessage(
						null,
						new FacesMessage(FacesMessage.SEVERITY_WARN,
								"Timesheet Details update failed.", ""));
			}
			loadOrGenerateTimesheetDetails(timesheet);
			RequestContext.getCurrentInstance().execute(
					"detailActivityDialog.hide()");
			RequestContext.getCurrentInstance().addPartialUpdateTarget(
					"timesheetForm");

		} else {
			System.out.println("INVALID...");
			projectAssignmentTimesheetDetails.clear();
			projectAssignmentTimesheetDetails
					.addAll(projectAssignmentTimesheetDetailDAO
							.getProjectAssignmentTimesheetDetails(selectedTimesheetDetail
									.getTimesheetdetailId()));
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_WARN,
							"Details were not saved.", ""));
		}

	}

	// Not used
	public void onHideActivityDialog() {
		System.out.println("Hiding...");
		loadOrGenerateTimesheetDetails(timesheet);
		RequestContext.getCurrentInstance().execute(
				"detailActivityDialog.hide()");
		RequestContext.getCurrentInstance().addPartialUpdateTarget(
				"timesheetForm");
	}

	public boolean validateAssignmentActivity() {
		System.out.println("Validating...");
		boolean VALID = true;

		String totalHoursString = "0:0";

		boolean ENTRY_FOUND = false;

		for (ProjectAssignmentTimesheetDetail projectAssignmentTimesheetDetail : projectAssignmentTimesheetDetails) {

			if (projectAssignmentTimesheetDetail.getActivity() != null
					&& !projectAssignmentTimesheetDetail.getActivity().equals(
							"")) {
				projectAssignmentTimesheetDetail.setACTIVITY_ENTERED(true);
			} else {
				projectAssignmentTimesheetDetail.setACTIVITY_ENTERED(false);
			}
			System.out.println(projectAssignmentTimesheetDetail.getTimeSpent());
			System.out.println(projectAssignmentTimesheetDetail.getTimeSpent()
					.equals("00:00"));
			if (projectAssignmentTimesheetDetail.getTimeSpent() == null
					|| projectAssignmentTimesheetDetail.getTimeSpent().equals(
							"00:00")
					|| projectAssignmentTimesheetDetail.getTimeSpent().equals(
							"")) {
				System.out.println("time not entered...");
				projectAssignmentTimesheetDetail.setTIME_ENTERED(false);
			} else {
				System.out.println("time entered...");
				projectAssignmentTimesheetDetail.setTIME_ENTERED(true);
				if (ValidationUtil.validate24HoursTime(
						projectAssignmentTimesheetDetail.getTimeSpent(),
						projectAssignmentTimesheetDetail.getEmployeeProject()
								.getProject().getProjectName()
								+ " time spent ", "",
						FacesContext.getCurrentInstance()) != null) {
					VALID = false;
					projectAssignmentTimesheetDetail.setTIME_VALID(false);
				} else {
					projectAssignmentTimesheetDetail.setTIME_VALID(true);
				}
			}

			if (projectAssignmentTimesheetDetail.isACTIVITY_ENTERED()
					&& !projectAssignmentTimesheetDetail.isTIME_ENTERED()) {
				VALID = false;
				FacesContext.getCurrentInstance().addMessage(
						null,
						new FacesMessage(FacesMessage.SEVERITY_WARN,
								projectAssignmentTimesheetDetail
										.getEmployeeProject().getProject()
										.getProjectName()
										+ " time is not entered.", ""));
			}

			if (!projectAssignmentTimesheetDetail.isACTIVITY_ENTERED()
					&& projectAssignmentTimesheetDetail.isTIME_ENTERED()) {
				VALID = false;
				FacesContext.getCurrentInstance().addMessage(
						null,
						new FacesMessage(FacesMessage.SEVERITY_WARN,
								projectAssignmentTimesheetDetail
										.getEmployeeProject().getProject()
										.getProjectName()
										+ " activity is not entered.", ""));
			}

			if (projectAssignmentTimesheetDetail.isACTIVITY_ENTERED()
					|| projectAssignmentTimesheetDetail.isTIME_ENTERED())
				ENTRY_FOUND = true;

			if (projectAssignmentTimesheetDetail.getTimeSpent() != null
					&& !projectAssignmentTimesheetDetail.getTimeSpent().equals(
							"")) {
				/*totalHoursString = WAMUtil.addTime(totalHoursString,
						projectAssignmentTimesheetDetail.getTimeSpent());*/
			}
		}

		if (ENTRY_FOUND) {
			
		} else {
			if (!selectedTimesheetDetail.getDayOfWeek().equals("Sunday")
					&& !selectedTimesheetDetail.getDayOfWeek().equals(
							"Saturday")) {
				VALID = false;
				FacesContext
						.getCurrentInstance()
						.addMessage(
								null,
								new FacesMessage(
										FacesMessage.SEVERITY_WARN,
										"At least one activity should be entered.",
										""));
			}
		}

		return VALID;
	}

	public void saveInTime() {
		System.out.println("Saving in time...");
		if (validateInTime(selectedTimesheetDetail)) {

		} else {
			selectedTimesheetDetail.setInTimeString(timesheetDetailDAO
					.getTimesheetDetail(
							selectedTimesheetDetail.getTimesheetdetailId())
					.getInTimeString());
		}
	}

	private boolean validateInTime(TimesheetDetail timesheetDetail) {
		boolean VALID = true;
		System.out.println("." + timesheetDetail.getInTimeString() + ".");

		if (!timesheetDetail.getDayOfWeek().equals("Sunday")
				&& !timesheetDetail.getDayOfWeek().equals("Saturday")) {

			boolean INVALID_TIME_FOUND = false;
			if (ValidationUtil.isEmpty(timesheetDetail.getInTimeString(),
					"In Time ", "In Time ", FacesContext.getCurrentInstance()) != null) {
				VALID = false;
				INVALID_TIME_FOUND = true;
			} else if (ValidationUtil.validate24HoursTime(
					timesheetDetail.getInTimeString(), "In Time is", "",
					FacesContext.getCurrentInstance()) != null) {
				VALID = false;
				INVALID_TIME_FOUND = true;
			}

			if (!INVALID_TIME_FOUND) {
				String timeDiff = ValidationUtil.getTimeDifference(
						timesheetDetail.getInTimeString(),
						timesheetDetail.getOutTimeString(), "");
				if (timeDiff != null && timeDiff.equals("INVALID TIMES")) {
					VALID = false;
					INVALID_TIME_FOUND = true;
				} else {
					timesheetDetail.setDuration(timeDiff);
				}
			}
		} else {
			boolean INVALID_TIME_FOUND = false;

			if (ValidationUtil.isEmpty(timesheetDetail.getInTimeString(),
					"In Time ", "In Time ", FacesContext.getCurrentInstance()) != null) {
				// timesheetDetail.setInTimeString("09:30");
			} else if (ValidationUtil.validate24HoursTime(
					timesheetDetail.getInTimeString(), "In Time is", "",
					FacesContext.getCurrentInstance()) != null) {
				VALID = false;
				INVALID_TIME_FOUND = true;
			}

			if (!INVALID_TIME_FOUND) {
				String timeDiff = ValidationUtil.getTimeDifference(
						timesheetDetail.getInTimeString(),
						timesheetDetail.getOutTimeString(), "");
				if (timeDiff != null && timeDiff.equals("INVALID TIMES")) {
					VALID = false;
					INVALID_TIME_FOUND = true;
				} else {
					timesheetDetail.setDuration(timeDiff);
				}
			}
		}

		System.out.println("VALID: " + VALID);
		return VALID;
	}

	public void saveOutTime() {
		System.out.println("Saving out time...");
		if (validateOutTime(selectedTimesheetDetail)) {

		} else {
			selectedTimesheetDetail.setOutTimeString(timesheetDetailDAO
					.getTimesheetDetail(
							selectedTimesheetDetail.getTimesheetdetailId())
					.getOutTimeString());
		}
	}

	private boolean validateOutTime(TimesheetDetail timesheetDetail) {
		boolean VALID = true;
		System.out.println("." + timesheetDetail.getOutTimeString() + ".");

		if (!timesheetDetail.getDayOfWeek().equals("Sunday")
				&& !timesheetDetail.getDayOfWeek().equals("Saturday")) {
			System.out.println("NOT SS");
			boolean INVALID_TIME_FOUND = false;
			if (ValidationUtil
					.isEmpty(timesheetDetail.getOutTimeString(), "Out Time ",
							"Out Time ", FacesContext.getCurrentInstance()) != null) {
				VALID = false;
				INVALID_TIME_FOUND = true;
			} else if (ValidationUtil.validate24HoursTime(
					timesheetDetail.getOutTimeString(), "Out Time is", "",
					FacesContext.getCurrentInstance()) != null) {
				VALID = false;
				INVALID_TIME_FOUND = true;
			}

			if (!INVALID_TIME_FOUND) {
				String timeDiff = ValidationUtil.getTimeDifference(
						timesheetDetail.getInTimeString(),
						timesheetDetail.getOutTimeString(), "");
				if (timeDiff != null && timeDiff.equals("INVALID TIMES")) {
					VALID = false;
					INVALID_TIME_FOUND = true;
				} else {
					timesheetDetail.setDuration(timeDiff);
				}
			}
		} else {
			boolean INVALID_TIME_FOUND = false;

			if (ValidationUtil
					.isEmpty(timesheetDetail.getOutTimeString(), "Out Time ",
							"Out Time ", FacesContext.getCurrentInstance()) != null) {
				// timesheetDetail.setInTimeString("09:30");
			} else if (ValidationUtil.validate24HoursTime(
					timesheetDetail.getOutTimeString(), "Out Time is", "",
					FacesContext.getCurrentInstance()) != null) {
				VALID = false;
				INVALID_TIME_FOUND = true;
			}

			if (!INVALID_TIME_FOUND) {
				String timeDiff = ValidationUtil.getTimeDifference(
						timesheetDetail.getInTimeString(),
						timesheetDetail.getOutTimeString(), "");
				if (timeDiff != null && timeDiff.equals("INVALID TIMES")) {
					VALID = false;
					INVALID_TIME_FOUND = true;
				} else {
					timesheetDetail.setDuration(timeDiff);
				}
			}
		}

		System.out.println("VALID: " + VALID);
		return VALID;
	}

	public TimesheetDetail getSelectedTimesheetDetail() {
		return selectedTimesheetDetail;
	}

	public void setSelectedTimesheetDetail(
			TimesheetDetail selectedTimesheetDetail) {
		this.selectedTimesheetDetail = selectedTimesheetDetail;
	}

	public Long getApproverId() {
		return approverId;
	}

	public void setApproverId(Long approverId) {
		this.approverId = approverId;
	}

	public Map<String, Long> getApproversMap() {
		return approversMap;
	}

	public void setApproversMap(Map<String, Long> approversMap) {
		this.approversMap = approversMap;
	}

	public Employee getApprover() {
		return approver;
	}

	public void setApprover(Employee approver) {
		this.approver = approver;
	}

	public boolean isIN_PROJECT() {
		return IN_PROJECT;
	}

	public void setIN_PROJECT(boolean iN_PROJECT) {
		IN_PROJECT = iN_PROJECT;
	}

	public List<ProjectAssignmentTimesheetDetail> getProjectAssignmentTimesheetDetails() {
		return projectAssignmentTimesheetDetails;
	}

	public void setProjectAssignmentTimesheetDetails(
			List<ProjectAssignmentTimesheetDetail> projectAssignmentTimesheetDetails) {
		this.projectAssignmentTimesheetDetails = projectAssignmentTimesheetDetails;
	}

	public TimesheetDetail getSelectedTimesheetDetailEmail() {
		return selectedTimesheetDetailEmail;
	}

	public void setSelectedTimesheetDetailEmail(
			TimesheetDetail selectedTimesheetDetailEmail) {
		this.selectedTimesheetDetailEmail = selectedTimesheetDetailEmail;
	}

	public boolean isSHOW_TIMESHEET_WARN_MESSAGE() {
		return SHOW_TIMESHEET_WARN_MESSAGE;
	}

	public void setSHOW_TIMESHEET_WARN_MESSAGE(
			boolean sHOW_TIMESHEET_WARN_MESSAGE) {
		SHOW_TIMESHEET_WARN_MESSAGE = sHOW_TIMESHEET_WARN_MESSAGE;
	}
}
